home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 262_01.zip / CMENU.C < prev    next >
Text File  |  1993-04-14  |  7KB  |  243 lines

  1. /********************************************************
  2.  *              CMENU (Assembler Version)               *
  3.  *                                                      *
  4.  *        A compiler for menu driven programs           *
  5.  *                  by Robert Ramey                     *
  6.  ********************************************************/
  7. #include "stdio.h"
  8. #include "symdef.h"
  9.  
  10. #define QUOTE   '\''    /* character used for quote by assembler */
  11. #define MAXDEPTH 10 /* Maximum number of digits in menu code */
  12. #define MAXLINE 128 /* Maximum length of any line in menu */
  13. #define MAXMENUS 50 /* Maximum number of menus */
  14. #define MAXSIZE 11  /* Space reserved for a symbol */
  15.  
  16. SYMBOLTABLE *mtable;    /* Accumulates menus */
  17. SYMBOLTABLE *atable;    /* Stores external symbols */
  18.  
  19. typedef struct mline {
  20.     struct mline *link;
  21.     char mtext[2];
  22.     } MLINE;
  23.  
  24.  
  25. char *marray[MAXMENUS];
  26. int mindex;
  27. int strcmp();
  28. char *strmov();
  29.  
  30. main(argc,argv)
  31. int argc;
  32. char *argv[];
  33. {
  34.     moat(2000);
  35.     mtable = symmk(sizeof(MLINE *), MAXMENUS);
  36.     if(!mtable){
  37.         fprintf(stderr, "Not enough memory");
  38.         exit(1);
  39.     }
  40.     load();
  41.     qsort(marray, mindex + 1, strcmp);
  42.     generate(); /* generate c code for menus */
  43. }
  44. load(){
  45.     char line[MAXLINE];
  46.     MLINE *last, *tptr; /* last element allocated in menu list */
  47.     int i, errflag;
  48.     
  49.     errflag = FALSE;
  50.  
  51.     /* load nul symbol corresponding to root menu */
  52.     marray[mindex = 0] = symadd(mtable, "");
  53.     last = NULL;
  54.     while(gets(line)){
  55.         if(isspace(line[0])){
  56.             if(errflag) continue;
  57.             for(i = 1;isspace(line[i]);++i);
  58.             tptr =
  59.             malloc(sizeof(char *) + strlen(line + i) + 1);
  60.             if(last)
  61.                 last->link = tptr;
  62.             else
  63.                 *(MLINE **)
  64.                 symdat(mtable,marray[mindex]) = tptr;
  65.             last = tptr;
  66.             last->link = NULL;
  67.             strmov(last->mtext, line + i);
  68.         }
  69.         else{
  70.             if(symlkup(mtable, line)){
  71.                 fprint(stderr,"%s menu repeated\n");
  72.                 errflag = TRUE;
  73.             }
  74.             else{
  75.                 marray[++mindex] =symadd(mtable, line);
  76.                 last = NULL;
  77.                 errflag = FALSE;
  78.             }
  79.         }
  80.     }
  81. }
  82. generate(){
  83.     MLINE *mptr;
  84.     char sfix[2],c, cbuffer[MAXDEPTH], *current, *next;
  85.     char s1[MAXLINE], s2[MAXSIZE], s3[MAXSIZE];
  86.     int litcount, i;
  87.  
  88.     /* preamble */
  89.     printf(";Compiled by CMENU\n");
  90.     printf("\t.HD64\n");
  91.     printf("\tDSEG\n");
  92.     printf("\tPUBLIC\tM?\n");
  93.     printf("\tEXTRN\tMENU?,ACTION?,HIST?\n");
  94.  
  95.     atable = symmk(0, MAXMENUS * 4);
  96.     if(!atable){
  97.         fprintf(stderr, "Not enough memory");
  98.         exit(1);
  99.     }
  100.     symadd(atable,"MENU?");
  101.     symadd(atable,"ACTION?");
  102.     symadd(atable,"HIST?");
  103.     i = 0;
  104.     next = marray[mindex];
  105.     do{
  106.         current = next;
  107.         if(mindex){
  108.             next = marray[mindex - 1];
  109.             if(strncmp(next, current, strlen(current) - 1))
  110.                 printf("menu %s has no father\n"
  111.                     ,current);
  112.         }
  113.  
  114.         /* generate external statements for action routines */
  115.         c = '\t';
  116.         mptr = *(MLINE **)symdat(mtable, current);
  117.         while(mptr = mptr->link){
  118.             /* check for continuation lines */
  119.             if(mptr->mtext[1] != '.') continue;
  120.             if(1 < mksym(mptr->mtext, s1, s2, s3)
  121.             && !symlkup(atable, s2)){
  122.                 if(c == '\t')
  123.                     printf("\tEXTRN");
  124.                 putchar(c);
  125.                 printf(s2);
  126.                 symadd(atable, s2);
  127.                 c = ',';
  128.             }
  129.         }
  130.         if(c != '\t')
  131.             putchar('\n');
  132.  
  133.         /* generate menu data structures */
  134.         litcount = i;
  135.         mptr = *(MLINE **)symdat(mtable, current);
  136.         printf("M%s?:\tDW\tL%d?\n",current,++i);
  137.         while(mptr = mptr->link){
  138.             /* check for continuation lines */
  139.             if(mptr->mtext[1] != '.') continue;
  140.             printf("\tDW\tL%d?,",++i);
  141.             switch(mksym(mptr->mtext,s1,s2,s3)){
  142.             case 3:
  143.             case 2:
  144.                 printf("%s,%s\n", s2, s3);
  145.                 break;
  146.             case 1:
  147.                 sfix[0] = mptr->mtext[0];
  148.                 sfix[1] = NULL;
  149.                 strmov(strmov(cbuffer, current),sfix);
  150.                 if(symlkup(mtable, cbuffer)){
  151.                     printf("MENU?,M%s?\n",cbuffer);
  152.                 }
  153.                 else
  154.                     printf("ACTION?,HIST?\n");
  155.             }
  156.         }
  157.         printf("\tDW\t0\n");
  158.  
  159.         /* generate literals */
  160.         i = litcount;
  161.         mptr = *(MLINE **)symdat(mtable, current);
  162.         printf("L%d?:",++i);
  163.         while(mptr){
  164.             printf("\tDB\t\'");
  165.             qout(mptr->mtext);
  166.             mptr = mptr->link;
  167.             /* figure in continuation lines */
  168.             if(mptr == NULL)
  169.                 printf("',0\n");
  170.             else
  171.             if(mptr->mtext[1] == '.')
  172.                 printf("',0\nL%d?:",++i);
  173.             else
  174.                 printf("',%d,%d\n", CR, LF);
  175.         }
  176.     }
  177.     while(mindex--);
  178.     printf("\tEND\n");
  179. }
  180. /**************************************************************
  181. qout - output a quoted string. QUOTE character gets special
  182. treatment.
  183. ***************************************************************/
  184. qout(s)
  185. char *s;
  186. {
  187.     char c;
  188.     while(c = *s++){
  189.         switch(c){
  190.         case QUOTE:
  191.             printf("%c,%d,%c",QUOTE,QUOTE,QUOTE);
  192.             break;
  193.         case ';':
  194.             return;
  195.         default:
  196.             putchar(c);
  197.         }
  198.     }
  199. }
  200. int
  201. mksym(instring, sa)
  202. char *instring, *sa;
  203. {
  204.     char c, *cptr,*s, **sb;
  205.     int i, j;
  206.  
  207.     sb = &sa;
  208.     s = *sb++;
  209.     cptr = ";()";
  210.     c = *cptr++;
  211.     i = 0;
  212.     while(i < 3){
  213.         if(*instring == NULL){
  214.             ++i;
  215.             *s = NULL;
  216.             break;
  217.         }
  218.         if(*instring == c){
  219.             ++i;
  220.             *s = NULL;
  221.             s = *sb++;
  222.             c = *cptr++;
  223.             ++instring;
  224.         }
  225.         else
  226.             *s++ = *instring++;
  227.     }
  228.     for(j = i;j < 3;++j)
  229.         *sb++ = "0";
  230.     sb = &sa + 1;
  231.     for(j = 1;j < 3;++j, ++sb){
  232.         if(isalpha(**sb)){
  233.             strupr(*sb);
  234.             strcat(*sb, "?");
  235.         }
  236.         else
  237.         if(**sb == NULL)
  238.             strmov(*sb, "0");
  239.     }
  240.     return i;
  241. }
  242.      }
  243.         if(*in